package com.wit.witmg.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wit.witmg.entity.DeviceSession;
import com.wit.witmg.entity.TMonitDust;
import com.wit.witmg.mapper.TMonitDustMapper;
import com.wit.witmg.service.ITMonitDustService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wit.witmg.util.ErrorCode;
import com.wit.witmg.util.JsonResult;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author bob
 * @since 2025-08-11
 */
@Service
public class TMonitDustServiceImpl extends ServiceImpl<TMonitDustMapper, TMonitDust> implements ITMonitDustService {

    private static final int COMMAND_TIMEOUT = 10; // 命令超时时间(秒)
    // 使用ConcurrentHashMap保证线程安全
    private final Map<String, DeviceSession> deviceConnections = new ConcurrentHashMap<>();

    // 命令响应等待池
    private final Map<String, CompletableFuture<String>> pendingCommands = new ConcurrentHashMap<>();

    @Override
    public Object add(HttpServletRequest request, String json) {
        TMonitDust t= JSON.parseObject(json,TMonitDust.class);
        if(t.getId()!=null && t.getId()>0){
            boolean bl=  updateById(t);
            if(!bl){
                return JsonResult.error(ErrorCode.ERR_504);
            }
            return JsonResult.success(t);
        }

        return JsonResult.error(ErrorCode.ERR_200);
    }

    @Override
    public Object get(HttpServletRequest request, Long dt0, Long dt1, String sid, String loca) {
//        返回date在dt0和dt1之间的数据（没有dt0，则返回dt1之前的20条，没有dt1，则返回dt0之后的20条，都没有，则返回最后20条），若有sid则同时根据sid筛选，若有loca则同时根据loca筛选
        LambdaQueryWrapper<TMonitDust> qw = new LambdaQueryWrapper<>();
        qw.orderByDesc(TMonitDust::getId);
        // 处理 sid 筛选
        if (sid != null && !sid.isEmpty()) {
            qw.eq(TMonitDust::getSid, sid);
        }
        // 处理 loca 筛选
        if (loca != null && !loca.isEmpty()) {
            qw.eq(TMonitDust::getLoca, loca);
        }
        // 处理时间范围筛选
        if (dt0 != null && dt1 != null) {
            // 查询 date 在 dt0 和 dt1 之间的数据
            qw.between(TMonitDust::getDate, dt0, dt1);
        } else if (dt1 != null) {
            // 查询早于 dt1 的最近 24 条数据
            qw.lt(TMonitDust::getDate, dt1);
            // 注意：分页限制需要在查询时处理，此处仅构建查询条件
        } else if (dt0 != null) {
            // 查询晚于 dt0 的最近 20 条数据
            qw.gt(TMonitDust::getDate, dt0);
        }else {
            qw.last("limit 200");
        }

        return JsonResult.success(list(qw));
    }

    @Override
    public void addConnection(Integer sbid, DeviceSession session) {
        deviceConnections.put(sbid+"", session);
    }

    @Override
    public DeviceSession getConnection(Integer sbid) {
        return deviceConnections.get(sbid+"");
    }

    @Override
    public void removeConnection(Integer sbid) {
        DeviceSession session = deviceConnections.remove(sbid+"");
        if (session != null) {
            try {
                session.getSocket().close();
            } catch (IOException e) {
                // 忽略关闭异常
            }
        }
        // 清理该设备所有等待中的命令
        pendingCommands.entrySet().removeIf(entry ->
                entry.getKey().startsWith(sbid + ":"));
    }

    @Override
    public Object sendCommandToDevice(Integer sbid, String command) {
        if(command==null){
            command="+wifidatashot:";
        }
        // 记录命令日志
        DeviceSession session = getConnection(sbid);
        if (session == null) {
            return JsonResult.error( "设备未连接");
        }
        // 生成唯一命令ID
        String commandId = sbid + ":cxzt";
//        session.setPendingCommandId(commandId);
        System.out.println("【发送命令】sbid: " + sbid + ", command: " + command + ", commandId: " + commandId);
        try {
            CompletableFuture<String> responseFuture = new CompletableFuture<>();
            pendingCommands.put(commandId, responseFuture);
            // 设置超时
            ScheduledFuture<?> timeoutFuture = Executors.newSingleThreadScheduledExecutor()
                    .schedule(() -> {
                        if (!responseFuture.isDone()) {
                            responseFuture.completeExceptionally(new TimeoutException("设备响应超时"));
                            pendingCommands.remove(commandId);
//                            session.clearPendingCommand();
                        }
                    }, COMMAND_TIMEOUT, TimeUnit.SECONDS);

            // 发送命令
            session.getWriter().println(command);
            try {
                String response = responseFuture.get(COMMAND_TIMEOUT + 1, TimeUnit.SECONDS);
                return JsonResult.success(response);
            } catch (TimeoutException e) {
                return JsonResult.error("设备响应超时");
            } catch (Exception e) {
                return JsonResult.error("命令执行失败: " + e.getMessage());
            } finally {
                timeoutFuture.cancel(true);
//                session.clearPendingCommand();
            }
        } catch (Exception e) {
            removeConnection(sbid);
            return JsonResult.error("命令发送失败: " + e.getMessage());
        }
    }

    @Override
    public void handleDeviceMessage(Integer sbid, String message) {
        DeviceSession session = getConnection(sbid);
        if (session == null) return;
        String pendingCommandId = sbid + ":cxzt";
//        String pendingCommandId = session.getPendingCommandId();
        System.out.println("【处理响应】deviceId: " + sbid + ", message: " + message + ", pendingCommandId: " + pendingCommandId);
//        if (pendingCommandId != null) {
        CompletableFuture<String> future = pendingCommands.get(pendingCommandId);
        if (future != null && !future.isDone()) {
            future.complete(message);
            pendingCommands.remove(pendingCommandId);
//                session.clearPendingCommand();
        }
    }
}
